#include <pthread.h>
#include <iostream>
#include <vector>
#include "../../src/purg.h"


struct thread_data
{
  std::vector<int>  data;
  purg::parallel_gen  *generator;
  size_t               num_to_do;
};


void  *fill_vector ( void *data )
{
  struct thread_data &td = *static_cast<struct thread_data *> ( data );
  td.data.resize ( td.num_to_do );
  for ( size_t i = 0 ; i != td.num_to_do ; i++ )
  {
    td.generator->get ( td.data[i] , 10 , 1000000000 );
  }
  pthread_exit ( 0 );
  return 0;
}

bool  remove_data ( std::vector<int> &master , std::vector<int> &thread )
{
  std::vector<int>::iterator cur_master = master.begin();
  std::vector<int>::iterator cur_thread = thread.begin();
  while ( cur_thread != thread.end() )
  {
    if ( *cur_thread == *cur_master )
    {
      *cur_master = 0;
      cur_thread++;
    }
    else
    {
      cur_master++;
      if ( cur_master == master.end() )
        return false;
    }
  }
  return true;
}

int main ( int argc , char **argv )
{
  purg::parallel_gen  gen1 ( 100 , 100 , 100 );
  purg::parallel_gen  gen2 ( 100 , 100 , 100 );
  struct thread_data  tds[100];
  pthread_t  threads[100];

  for ( size_t i = 0 ; i != 100 ; i++ )
  {
    tds[i].generator = &gen2;
    tds[i].num_to_do = 10000;
    pthread_create ( & (threads[i]) , 0 , fill_vector , static_cast<void *> ( &(tds[i]) ) );
  }

  std::vector<int>  master ( 1000000 );
  for ( size_t i = 0 ; i != 1000000 ; i++ )
  {
    gen1.get ( master[i] , 10 , 1000000000 );
  }

  for ( size_t i = 0 ; i != 100 ; i++ )
  {
    pthread_join ( threads[i] , 0 );
    if ( !remove_data ( master , tds[i].data ) )
      std::cout << "Thread safe check failed " << i << std::endl;
  }

}

